﻿using System;
using System.Collections.Generic;
using System.Linq.Expressions;

// ReSharper disable InconsistentNaming

namespace FadeLang.Ast
{
    public class InternalFunction
    {
        private static InternalFunction instance;

        private readonly Dictionary<string, Delegate> functionsDictionary = new Dictionary<string, Delegate>();

        private InternalFunction() {
            //add build-in functions
            Expression<Action<object>> print = i => Console.Write(i);
            functionsDictionary.Add(nameof(print), print.Compile());

            Expression<Func<string>> read = () => Console.ReadLine();
            functionsDictionary.Add(nameof(read), read.Compile());
        }

        public static InternalFunction Instance => instance ?? (instance = new InternalFunction());

        public bool TryRun(FunctionCall functionCall, out dynamic returnValue) {
            var funcName = functionCall.Name;

            if (functionsDictionary.ContainsKey(funcName)) {
                var func = functionsDictionary[funcName];
                returnValue = func.DynamicInvoke(functionCall.ArgValueList.ToArray());
                return true;
            }
            returnValue = null;
            return false;
        }
    }
}